﻿using EkStudio.com.bean.xml.BillModule;
using EkStudio.com.bean.xml.reflection;
using EkStudio.com.bean.xml.RootInterface;
using EkStudio.com.bean.xml.RootInterface.DataSource;
using EkStudio.com.bean.xml.RootInterface.FieldEvent;
using EkStudio.com.bean.xml.RootInterface.language;
using EkStudio.com.common.unit;
using EkStudio.com.bean.xml.ProjectVersion;
using System.Collections.Generic;
using EkStudio.com.bean.xml.RootInterface.Field;

namespace EkStudio.com.bean.xml.BillDictionary
{
    /// <summary>
    /// 字典
    /// </summary>
    [XmlRootElement("root")]
    public class BillDicModuleItem : BillFormatModule
    {

        private log4net.ILog logger = log4net.LogManager.GetLogger(typeof(BillDicModuleItem));

        private BillDicModuleRoot rootProperties = null;

        private BillSourceRoot dataSource = null;

        private BillDicModuleFieldsRoot fieldsProperties = null;

        private BillFieldsI18nRoot i18nProperties = null;


        [XmlElement(Name = "gsModuleProperties")]
        public BillDicModuleRoot RootProperties
        {
            get { return rootProperties; }
            set { rootProperties = value; rootProperties.ParentBean = this; }
        }

        [XmlElement(Name = "gsDataSource")]
        public BillSourceRoot DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }

        [XmlElement(Name = "fieldsProperties")]
        public BillDicModuleFieldsRoot FieldsProperties
        {
            get { return fieldsProperties; }
            set { fieldsProperties = value; fieldsProperties.ParentBean = this; }
        }


        [XmlTransient]
        public BillDataFillRoot DataFill
        {
            get { return null; }
            set { }
        }
        [XmlElement(Name = "i18nProperties")]
        public BillFieldsI18nRoot I18nProperties
        {
            get { return i18nProperties; }
            set { i18nProperties = value; }
        }

        [XmlTransient]
        public object ParentBean
        {
            get { return null; }
            set { }
        }
        [XmlTransient]
        public BillUiGroupRoot UiField
        {
            get { return null; }
            set { }
        }


        /// <summary>
        /// 初始化数据源
        /// </summary>
        public void autoInitDataSource()
        {
            if (ReadOly) return;//只有在内容在非只读的情况下执行

            BillSourceRoot sourceRoot = null;
            List<BillSourceTabItems> billTabs = null;
            if (this.DataSource != null)
            {         //如果已经存在数据源根节点
                sourceRoot = this.DataSource;
                if (sourceRoot.TableItems != null)
                { //判断是否存在内容
                    billTabs = sourceRoot.TableItems;
                }
                else
                {
                    billTabs = new List<BillSourceTabItems>();
                    sourceRoot.TableItems = billTabs;
                }
            }
            else
            {
                sourceRoot = new BillSourceRoot();
                billTabs = new List<BillSourceTabItems>();
                sourceRoot.TableItems = billTabs;
                this.DataSource = sourceRoot;
            }
            //清空数据重新生成
            for (int i = 0; i < billTabs.Count; i++)
            {
                if (billTabs[i].Fields != null)
                {
                    billTabs[i].Fields.Clear();
                }
                else
                {
                    billTabs[i].Fields = new List<BillSourceFields>();
                }
            }

            if (fieldsProperties != null && fieldsProperties.Fields != null)
            {
                List<BillUiFieldsItem> fields = fieldsProperties.Fields;
                BillSourceTabItems sourceTab = null;
                if (billTabs.Count > 0) sourceTab = billTabs[0];
                if (sourceTab == null)
                {
                    sourceTab = new BillSourceTabItems();
                    sourceTab.Key = "0";
                    sourceTab.CanSave = true;
                    sourceTab.TableName = "Dic_" + this.getKey();
                    sourceTab.Fields = new List<BillSourceFields>();
                    billTabs.Add(sourceTab);
                }
                sourceTab.Caption = this.getCaption();
                if (sourceTab.Fields == null) sourceTab.Fields = new List<BillSourceFields>();
                if (fields.Count > 0)
                {
                    for (int k = 0; k < fields.Count; k++)
                    {
                        BillUiFieldsItem field = fields[k];
                        string dataSource = field.DataProperty.DataSource;
                        if (dataSource != null && dataSource != "" && !field.DataProperty.VirtualType)
                        {
                            BillSourceFields source = new BillSourceFields();
                            source.Key = dataSource;
                            source.Type = field.DataProperty.DataType;
                            source.Caption = field.Caption;
                            source.Size = field.DataProperty.Size;
                            source.DtFormat = field.DataProperty.DtFormat;
                            source.FnNotNull = field.DataProperty.FnNotNull;
                            source.LanguageTexts = field.LanguageTexts;
                            sourceTab.Fields.Add(source);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 初始化多语言
        /// </summary>
        /// <param name="version"></param>
        public void autoInitLanguage(ProjectVersionItem version)
        {
            if (ReadOly) return;
            if (i18nProperties == null)
            {
                i18nProperties = new BillFieldsI18nRoot();
            }
            if (i18nProperties.Group == null)
            {
                i18nProperties.Group = new List<BillFieldsI18nGroup>();
            }
            List<BillFieldsI18nGroup> groups = i18nProperties.Group;
            if (version != null && version.Languages != null && version.Languages.Item != null)
            {
                List<ProjectLanguageElement> languages = version.Languages.Item;
                for (int i = 0; i < languages.Count; i++)
                {
                    string key = languages[i].Name;
                    string default_ = languages[i].Default_;
                    BillFieldsI18nGroup group = null;
                    for (int k = 0; k < groups.Count; k++)
                    {
                        if (groups[k].Key == key)
                        {
                            group = groups[k];
                            break;
                        }
                    }
                    if (group == null)
                    {
                        group = new BillFieldsI18nGroup();
                        group.Key = key;
                        group.Element = new List<BillFieldsI18nElement>();
                        groups.Add(group);
                    }
                    if (group.Element == null) group.Element = new List<BillFieldsI18nElement>();
                    createLanElement(group, (default_ == "Y"));

                }

            }

        }

        /// <summary>
        /// 字段组多语言
        /// </summary>
        /// <param name="group"></param>
        /// <param name="default_"></param>
        private void createLanElement(BillFieldsI18nGroup group, bool default_)
        {
            if (this.fieldsProperties != null && this.fieldsProperties.Fields != null && fieldsProperties.Fields.Count > 0)
            {
                //添加字段多语言
                List<BillUiFieldsItem> item = fieldsProperties.Fields;
                for (int k = 0; k < item.Count; k++)
                {
                    BillUiFieldsItem field = item[k];
                    if (!existLanguage(group, field.LanguageTexts, default_ ? field.Caption : ""))
                    {
                        BillFieldsI18nElement ele = new BillFieldsI18nElement();
                        ele.Key = field.LanguageTexts;
                        ele.Value = default_ ? field.Caption : "";
                        group.Element.Add(ele);
                    }
                }
            }

        }

        /// <summary>
        /// 判断多语言是否已经存在
        /// </summary>
        /// <param name="group"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private bool existLanguage(BillFieldsI18nGroup group, string key, string caption)
        {
            bool result = false;
            if (group != null && group.Element != null)
            {
                foreach (BillFieldsI18nElement i18 in group.Element)
                {
                    if (i18.Key == key)
                    {
                        if (caption != "")//存在时，如果是默认语言则修改为当前
                        {
                            i18.Value = caption;
                        }
                        result = true;
                        break;
                    }
                }
            }

            return result;
        }


        public object Clone()
        {
            BillDicModuleItem clone = new BillDicModuleItem();
            clone.RootProperties   = RootProperties.Clone() as BillDicModuleRoot;
            clone.FieldsProperties = FieldsProperties.Clone() as BillDicModuleFieldsRoot;
            return clone;
        }

        public int getBillType()
        {
            return ProjectUtil.TYPE_DIC_MODULE;
        }

        public string getCaption()
        {
            return rootProperties.Caption;
        }

        public string getJavaPackage()
        {
            return "";
        }

        public string getKey()
        {
            return rootProperties.Key;
        }

        public string getLanguageText()
        {
            return rootProperties.LanguageTexts;
        }

        public string getVersion()
        {
            return rootProperties.RootVersion ;
        }

        public bool isReadOnly()
        {
            return ReadOly;
        }

        public void setReadOnly(bool read)
        {
            ReadOly = read;
        }

        private bool ReadOly = false;
    }
}
